﻿using System;
using System.Web.UI.WebControls;
using System.Web.UI;

using IdeaNMR.Shared.Utils;
using IdeaNMR.Web.Core;

using AjaxControlToolkit;

using ScrewTurn.Wiki;

namespace IdeaNMR.Web
{
    /// <summary>
    /// Summary description for IdeaNMR_BasePage
    /// </summary>
    /// <remarks>
    /// <para>
    /// IMPORTANT. Ajax control toolkit seems to generate false requests, where original query string is not present.
    /// Therefore all important request parameters must be saved in viewstate on first request.
    /// </para>
    /// </remarks>
    public class IdeaNMR_BasePage : ScrewTurn.Wiki.BasePage
    {
        private UserDataManager udm;

        /// <summary>
        /// Proxied UserDataManager for current user.
        /// </summary>
        protected UserDataManager UserData
        {
            get
            {
                if (this.udm == null) this.udm = UserDataManager.GetForUsername(ScrewTurnWikiFacade.Username);
                return this.udm;
            }
        }

        /// <summary>
        /// An update panel from basepage.
        /// Serves to inject script to the page from base page.
        /// </summary>
        /// <remarks>
        /// This control must be created during init phase otherwise script registration does not work.
        /// </remarks>
        protected UpdatePanel MasterUpdatePanel
        { get; set; }

        protected virtual void Page_PreInit(object sender, EventArgs e)
        {
            this.ViewStateEncryptionMode = ViewStateEncryptionMode.Always;

            #region Validate Authentication
            if (SessionFacade.LoginKey == null)
            {
                // ALISTAIR modified 23/08/2011
                // User has either not logged in or has logged out.
                //
                // When user tries to access data before logging in:
                //
                // 1. The original URL they were trying to access is saved
                // (actually the parent page, which is the UrlReferrer),
                // so that they could be re-directed here once logged in.
                //
                // 2. They are re-directed to the login page.  This is done by changing the
                // last segment of the URL to "Login.aspx", so that the full path will be
                // relative to the existing URL (i.e. same host/port number or web address)
                //
                // 3. The original parent page is set as a "Redirect" query parameter,
                // such that they can be re-directed to this page once logged in.
                //
                // 4. Redirect the parent page to the Login page (including redirect query parameter)

                // Original URL changed from the using only the central frame to using
                // the parent page (UrlReferrer)
                //UriBuilder origUri = new UriBuilder(Request.Url);
                UriBuilder origUri = new UriBuilder(Request.UrlReferrer);
                UriBuilder redirectUri = new UriBuilder(origUri.Uri);

                // break down the URL into its segments
                // and change the final segement to "Login.aspx"
                string[] segs = origUri.Uri.Segments;
                segs[segs.Length - 1] = "Login.aspx";

                // the redirect path becomes the path with segments re-joined
                redirectUri.Path = string.Join(string.Empty, segs);
                // should have redirect parameter back to original parent URL,
                // however, this does not work whenever the user has logged out,
                // so re-directing to the Main Page instead.
                //redirectUri.AddQueryParameter("Redirect", Tools.UrlEncode(origUri.Uri.ToString()));
                redirectUri.AddQueryParameter("Redirect", "/MainPage.ashx");
                
                // re-direct the current parent page to the Login URL
                RedirectParent(redirectUri.Uri);
            }

            // Verify if user is present at IdeaNMR Database

            if (!UserDataManager.Exists(ScrewTurnWikiFacade.Username)) UserDataManager.GetForUsername(ScrewTurnWikiFacade.Username);
            #endregion
        }

        protected virtual void Page_Init(object sender, EventArgs e)
        {
            this.MasterUpdatePanel = new UpdatePanel();
            this.Form.Controls.Add(this.MasterUpdatePanel);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <remarks>
        /// <para>Request querystring is transfered to ViewState on first request.</para>
        /// </remarks>
        protected virtual void Page_InitComplete(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                // Transfer Query String Parameters to ViewState
                foreach (var key in Request.QueryString.AllKeys)
                {
                    ViewState[key] = Request.QueryString[key];
                }
            }
        }

        protected void Page_Error(object sender, EventArgs e)
        {
            Exception ex = Server.GetLastError();
            this.Server.ClearError();

            if (ex is ApplicationException)
                this.RedirectOnError(((ApplicationException)ex).Message);
            else
                this.RedirectOnError(ex.ToString());
        }

        /// <summary>
        /// Redirects Parent Window to "Error.aspx"
        /// </summary>
        /// <param name="errMsg">The message that will go to Wiki Log.</param>
        public void RedirectOnError(string errMsg)
        {
            ScrewTurn.Wiki.Log.LogEntry(errMsg, ScrewTurn.Wiki.PluginFramework.EntryType.Error, ScrewTurnWikiFacade.Username);

            UriBuilder uri = new UriBuilder(ScrewTurnWikiFacade.MainUrl);
            uri.Path += "Error.aspx";
            string resp = string.Format(@"<script>parent.location='{0}';</script>", uri.Uri.ToString());

            if (this.MasterUpdatePanel == null) // Controls are not initialized, so page is not rendered async
                Response.Write(resp);
            else
                ToolkitScriptManager.RegisterClientScriptBlock(this.MasterUpdatePanel, typeof(UpdatePanel), "Redirection", resp, false);
        }

        public void RedirectParent(Uri target)
        {
            string resp = string.Format(@"<script>parent.location='{0}';</script>", target.ToString());
            if (this.MasterUpdatePanel == null) 
                Response.Write(resp);
            else
                ToolkitScriptManager.RegisterClientScriptBlock(this.MasterUpdatePanel, typeof(UpdatePanel), "Redirection", resp, false);
        }

        public IdeaNMR_BasePage()
        {
            //
            // TODO: Add constructor logic here
            //
        }
    }
}